package com.distributed.netty.client;

import com.distributed.netty.entity.Cache;
import com.distributed.netty.entity.ElementJob;
import com.distributed.netty.entity.Message;
import com.rcache.core.utils.EmailUtils;
import com.rcache.core.cache.Rcache;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.SimpleChannelInboundHandler;
import io.netty.handler.timeout.IdleState;
import io.netty.handler.timeout.IdleStateEvent;
import org.apache.log4j.Logger;

import javax.mail.MessagingException;
import java.io.UnsupportedEncodingException;
import java.net.Inet4Address;
import java.net.InetAddress;
import java.net.UnknownHostException;
import java.util.HashSet;
import java.util.LinkedList;
import java.util.Set;

/**
 * @desc 客户端消息回调手柄
 * @author gzy
 * @time 2022-06-05
 */
public class ChatHandler extends SimpleChannelInboundHandler<Object> {
    private Rcache rcache;
    private LinkedList<ElementJob> jobList;
    public ChatHandler(Rcache rcache, LinkedList<ElementJob> jobList) {
        LOG.debug("实例化客户端消息回调手柄");
        this.rcache=rcache;
        this.jobList=jobList;
    }

    Logger LOG=Logger.getLogger(ChatHandler.class);

    @Override
    protected void channelRead0(ChannelHandlerContext channelHandlerContext, Object msg) throws Exception {
        LOG.debug("进入客户端消息回调手柄");
        System.out.println(msg);
        Message message = (Message) msg;
        LOG.debug("接收到服务端的消息："+message.getMsg());
        Cache.set = message.getSlaves();
        //获取本机ip
        InetAddress inet4Address = Inet4Address.getLocalHost();
        String ipSelf = inet4Address.toString().split("/")[1];
        LOG.debug("本机ip为："+ipSelf+"，服务端保存的ip为："+message.getSendSlaveIp());
        //如果是本机ip则说明服务端收到并执行成功，移除这些job
        if (ipSelf.equals(message.getSendSlaveIp())){
            LOG.debug("收到服务端回信，删除之前发送的job");
            LOG.debug("job为："+message.getElementJobs());
            jobList.removeAll(message.getElementJobs());
        }else{
            Set<ElementJob> jobs = message.getElementJobs();
            if (jobs!=null){
                for (ElementJob job:jobs) {
                    switch (job.getJobType()){
                        case PUT:
                            rcache.put(job.getArgs()[0],job.getArgs()[1]);
                            break;
                        case DELETE:
                            rcache.remove(job.getArgs()[0]);
                            break;
                        case UPDATE:
                            rcache.replace(job.getArgs()[0],job.getArgs()[1]);
                            break;
                    }
                }
            }
        }
    }
    @Override
    public void handlerRemoved(ChannelHandlerContext ctx) throws Exception {
        LOG.error("服务端断开, channel对应的长id为:" + ctx.channel().id().asLongText());
        LOG.error("服务端断开, channel对应的短id为:" + ctx.channel().id().asShortText());
        String ip = ctx.channel().remoteAddress().toString().split(":")[0].replace("/","");
        LOG.error("服务端ip为:" + ip);
        //如果开启了预警系统则异步发送预警信息
        if (rcache.isWarning()){
            new Thread(new Runnable() {
                @Override
                public void run() {
                    //获取本机ip
                    InetAddress inet4Address = null;
                    try {
                        inet4Address = Inet4Address.getLocalHost();
                        String ipSelf = inet4Address.toString().split("/")[1];
                        //发送告警信息
                        EmailUtils.createMineMessage("Slave:"+ipSelf+" 预警信息","ip地址为:"+ip+"的master服务端宕机断线",rcache.getManagerEmail());
                    } catch (UnknownHostException | UnsupportedEncodingException | MessagingException e) {
                        throw new RuntimeException(e);
                    }
                }
            }).start();
        }
    }

    @Override
    public void userEventTriggered(ChannelHandlerContext ctx, Object evt) throws Exception {

        if (evt instanceof IdleStateEvent){
            IdleStateEvent event = (IdleStateEvent)evt;
            if (event.state()== IdleState.WRITER_IDLE){

                if (!jobList.isEmpty()){
                    //回复消息
                    Message replyMessage=new Message();
                    //对发送来的slave记录其ip 发送job在slave端验证如果是自己则删除job
                    replyMessage.setSlaves(Cache.set);
                    replyMessage.setMsg("我是slave 请求更新操作");
                    HashSet jobs=new HashSet();
                    jobs.addAll(jobList);
                    replyMessage.setElementJobs(jobs);
                    ctx.writeAndFlush(replyMessage);
//					jobList.clear();
                }else{
                    //回复消息
                    Message replyMessage=new Message();
                    replyMessage.setMsg("biubiu");
                    ctx.writeAndFlush(replyMessage);
                }
            }
        }
    }
}